{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "4b1e7f43-24ec-444e-b162-dd81dfe27266",
   "metadata": {},
   "source": [
    "# "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "c348c762-6123-48c5-8eb2-3e155a245d78",
   "metadata": {},
   "outputs": [],
   "source": [
    "import dora\n",
    "import pyarrow as pa\n",
    "import inspect"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ca596b24-37d6-4f6e-8efe-5df35500d2c5",
   "metadata": {},
   "outputs": [],
   "source": [
    "node = dora.Node()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "efedd4cf-7de9-43a6-96b0-54d9838f9813",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/peter/miniconda3/lib/python3.10/site-packages/zmq/backend/cython/../../../../.././libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /lib/x86_64-linux-gnu/libicuuc.so.72)\n",
      "No module named 'open3d'\n",
      "No module named 'yolov7_tt100k'\n",
      "No module named 'carla'\n",
      "No module named 'autoagents'\n",
      "No module named 'carla'\n",
      "No module named 'carla'\n",
      "No module named 'carla'\n",
      "No module named 'carla'\n",
      "No module named 'rospy'\n",
      "No module named 'mavsdk'\n",
      "No module named 'rospy'\n",
      "No module named 'sensor_msgs'\n",
      "No module named 'sensor_msgs'\n",
      "No module named 'sensor_msgs'\n",
      "Number of operators to watch 9\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import sys\n",
    "\n",
    "\n",
    "## Get all python files path in given directory\n",
    "def get_all_functions(path):\n",
    "    functions = []\n",
    "    paths = []\n",
    "    codes = []\n",
    "    for root, dirs, files in os.walk(path):\n",
    "        for file in files:\n",
    "            if file.endswith(\".py\"):\n",
    "                path = os.path.join(root, file)\n",
    "                with open(path, \"r\", encoding=\"utf8\") as f:\n",
    "                    ## add file folder to system path\n",
    "                    sys.path.append(root)\n",
    "                    ## import module from path\n",
    "                    try:\n",
    "                        module = __import__(file[:-3])\n",
    "                        ## get all functions in module\n",
    "                        for name, data in module.__dict__.items():\n",
    "                            # if inspect.isfunction(data):\n",
    "                            # ## Get function source code\n",
    "                            # print(data)\n",
    "                            # source = inspect.getsource(data)\n",
    "                            # functions.append(source)\n",
    "                            # paths.append(path)\n",
    "                            if inspect.isclass(data) and name == \"Operator\":\n",
    "                                # ## Get function source code\n",
    "                                # print(data)\n",
    "                                source = inspect.getsource(data.on_input)\n",
    "                                codes.append(source)\n",
    "                                functions.append(f.read())\n",
    "                                paths.append(file)\n",
    "\n",
    "                    except Exception as err:\n",
    "                        print(err)\n",
    "                        pass\n",
    "\n",
    "    return functions, paths, codes\n",
    "\n",
    "\n",
    "path = \"/home/peter/Documents/work/dora-drives\"\n",
    "files, paths, codes = get_all_functions(path)\n",
    "print(f\"Number of operators to watch {len(files)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "c4d11282-abe5-4600-9b48-c6314ee3c4be",
   "metadata": {},
   "outputs": [],
   "source": [
    "files.extend(paths)\n",
    "files.extend(codes)\n",
    "node.send_output(\"append\", pa.array(files))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "23bd449c-29e0-4b40-91b8-2e86408e92ab",
   "metadata": {},
   "outputs": [],
   "source": [
    "node.send_output(\"query\", pa.array([\"Can you only show 10 bounding boxes?\"]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "9c26d214-fb40-4679-aac0-d2e0fc399776",
   "metadata": {},
   "outputs": [],
   "source": [
    "event = node.next(timeout=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "0502e2ec-5c70-4664-8ad9-6c23bd9964b7",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = event[\"value\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "61cfa382-2775-4ad1-a4a8-fc9938a98995",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0                                          yolov5_op.py\n",
       "1     \"\"\" \\n# Yolov5 operator\\n\\n`Yolov5` object det...\n",
       "2         def on_input(\\n        self,\\n        dora...\n",
       "3                                     strong_sort_op.py\n",
       "4     \"\"\" \\n# Strong Sort operator\\n\\n`Strong sort` ...\n",
       "5         def on_input(\\n        self,\\n        dora...\n",
       "6                               obstacle_location_op.py\n",
       "7     \"\"\" \\n# Obstacle location operator\\n\\nThe obst...\n",
       "8         def on_input(\\n        self,\\n        dora...\n",
       "9                                               plot.py\n",
       "10    import time\\nfrom typing import Callable\\n\\nim...\n",
       "11        def on_input(\\n        self,\\n        dora...\n",
       "12                                          yolop_op.py\n",
       "13    \"\"\" \\n# yolop operator\\n\\n`yolop` recognizes l...\n",
       "14        def on_input(\\n        self,\\n        dora...\n",
       "dtype: object"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.to_pandas()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "64e13be4-9eb9-4b27-8710-5647da72aca4",
   "metadata": {},
   "outputs": [],
   "source": [
    "text = data[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "121cc3d1-1981-476e-816a-b06e22f34ef2",
   "metadata": {},
   "outputs": [],
   "source": [
    "node.send_output(\"prompt\", pa.array([f\"print hello world?\"]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "536e4b4f-f936-4647-8525-5f3fd22ba5e2",
   "metadata": {},
   "outputs": [],
   "source": [
    "event = node.next(timeout=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "302ffa43-51cf-4819-ac23-41f712e5c6c8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<pyarrow.lib.StringArray object at 0x7f58d01bac80>\n",
       "[\n",
       "  \"        \n",
       "        To print \"hello world\" in various programming languages, you can use the following code snippets:\n",
       "\n",
       "        Python:\n",
       "        ```python\n",
       "        print(\"Hello World!\")\n",
       "        ```\n",
       "        \n",
       "        JavaScript:\n",
       "        ```javascript\n",
       "        console.log(\"Hello World!\");\n",
       "        ```\n",
       "        \n",
       "        Java:\n",
       "        ```java\n",
       "        public class HelloWorld {\n",
       "            public static void main(String[] args) {\n",
       "                System.out.println(\"Hello World!\");\n",
       "            }\n",
       "        }\n",
       "        ```\n",
       "        \n",
       "        C:\n",
       "        ```c\n",
       "        #include <stdio.h>\n",
       "        int main() {\n",
       "            printf(\"Hello World!\\n\");\n",
       "            return 0;\n",
       "        }\n",
       "        ```\n",
       "        \n",
       "        C++:\n",
       "        ```c++\n",
       "        #include <iostream>\n",
       "        int main() {\n",
       "            std::cout << \"Hello World!\" << std::endl;\n",
       "            return 0;\n",
       "        }\n",
       "        ```\n",
       "        \n",
       "        Pick the language you're using and execute the corresponding code snippet to print \"Hello World\".\"\n",
       "]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "event[\"value\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "017b8808-7507-4105-8c99-09e1fd627a78",
   "metadata": {},
   "outputs": [],
   "source": [
    "node.send_output(\"prompt\", pa.array([f\"{text}  \\n Can you filter to show 10 bounding boxes. Respond with code only\"]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "db6cd33c-4f2d-4a44-8c9c-2ccef39fdb36",
   "metadata": {},
   "outputs": [],
   "source": [
    "event = node.next(timeout=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "66d260f9-412f-41d8-bf5e-1117bb87cc56",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<pyarrow.lib.StringArray object at 0x7f58d01bb5e0>\n",
       "[\n",
       "  \"        Sure, here's how you can modify the code to display the top 10 bounding boxes:\n",
       "\n",
       "```python\n",
       "def on_input(self, dora_input: dict, send_output: Callable[[str, bytes], None]):\n",
       "    \"\"\"\n",
       "    Handle image\n",
       "    Args:\n",
       "        dora_input[\"id\"] (str): Id of the input declared in the yaml configuration\n",
       "        dora_input[\"value\"] (arrow.array (UInt8)): Bytes message of the input\n",
       "        send_output (Callable[[str, bytes]]): Function enabling sending output back to dora.\n",
       "    \"\"\"\n",
       "    if dora_input[\"id\"] == \"image\":\n",
       "        frame = dora_input[\"value\"].to_numpy().reshape((IMAGE_HEIGHT, IMAGE_WIDTH, 4))\n",
       "        frame = frame[:, :, :3]\n",
       "\n",
       "        results = self.model(frame)  # includes NMS\n",
       "\n",
       "        # Sort the results by confidence score (highest first)\n",
       "        results.xyxy = sorted(results.xyxy, key=lambda x: x[5], reverse=True)\n",
       "\n",
       "        # Limit the output to the top 10 bounding boxes\n",
       "        results = results[:10]\n",
       "\n",
       "        arrays = [np.array(r.xyxy[0].cpu()).reshape(-1) for r in results]\n",
       "        arrays = [a[:, [0, 2, 1, 3, 4, 5]] for a in arrays]\n",
       "        for a in arrays:\n",
       "            a[4] *= 100\n",
       "        arrays = [a.astype(np.int32) for a in arrays]\n",
       "        arrays = pa.concat(pa.Array(arrays), axis=1)\n",
       "        send_output(\"bbox\", arrays.ravel(), dora_input[\"metadata\"])\n",
       "\n",
       "        return DoraStatus.CONTINUE\n",
       "```\n",
       "\n",
       "This code sorts the results by confidence score and then limits the output to the top 10 bounding boxes.\"\n",
       "]"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "event[\"value\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eddd6bf1-e994-4e54-b611-d8aced0475f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "node.send_output(\"clear\", pa.array([\"\"]))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
